#include <stdbool.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
#include <SLES/OpenSLES.h>
#include <SLES/OpenSLES_Android.h>
#include "logger.h"
#include "pcm-player.h"

// OpenSL ES相关变量
static SLObjectItf engineObject = NULL;
static SLEngineItf engineEngine = NULL;
static SLObjectItf outputMixObject = NULL;
static SLEnvironmentalReverbItf outputMixEnvironmentalReverb = NULL;
static SLObjectItf bqPlayerObject = NULL;
static SLPlayItf bqPlayerPlay = NULL;
static SLAndroidSimpleBufferQueueItf bqPlayerBufferQueue = NULL;
static SLVolumeItf bqPlayerVolume = NULL;

// 音频参数
static int g_channels = 0;
static int g_samplerate = 0;
static int g_bits_per_sample = 0;

// 缓冲区管理
#define BUFFER_COUNT 4
#define BUFFER_SIZE 8192
static unsigned char audio_buffers[BUFFER_COUNT][BUFFER_SIZE];
static volatile int current_buffer = 0;
static volatile bool is_playing = false;
static pthread_mutex_t buffer_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t buffer_cond = PTHREAD_COND_INITIALIZER;
static volatile bool buffer_ready[BUFFER_COUNT] = {false};

// 播放器状态
static player_ctrl_cmd_t current_state = PLAYER_CMD_STOP;

// 回调函数：当缓冲区播放完毕时调用
static void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void *context) {
    pthread_mutex_lock(&buffer_mutex);
    
    // 标记当前缓冲区已播放完毕
    buffer_ready[current_buffer] = false;
    current_buffer = (current_buffer + 1) % BUFFER_COUNT;
    
    // 通知写入线程
    pthread_cond_signal(&buffer_cond);
    
    pthread_mutex_unlock(&buffer_mutex);
}

// 检查OpenSL ES支持
static int check_opensles_support() {
    SLObjectItf tempEngineObject = NULL;
    SLEngineItf tempEngineEngine = NULL;
    SLresult result;

    // 创建引擎
    result = slCreateEngine(&tempEngineObject, 0, NULL, 0, NULL, NULL);
    if (SL_RESULT_SUCCESS != result) {
        dlog("OpenSL ES engine creation failed: %d\n", result);
        return 0;
    }

    // 实现引擎
    result = (*tempEngineObject)->Realize(tempEngineObject, SL_BOOLEAN_FALSE);
    if (SL_RESULT_SUCCESS != result) {
        dlog("OpenSL ES engine realize failed: %d\n", result);
        (*tempEngineObject)->Destroy(tempEngineObject);
        return 0;
    }

    // 获取引擎接口
    result = (*tempEngineObject)->GetInterface(tempEngineObject, SL_IID_ENGINE, &tempEngineEngine);
    if (SL_RESULT_SUCCESS != result) {
        dlog("OpenSL ES get engine interface failed: %d\n", result);
        (*tempEngineObject)->Destroy(tempEngineObject);
        return 0;
    }

    // 清理临时对象
    (*tempEngineObject)->Destroy(tempEngineObject);
    
    dlog("OpenSL ES is supported!\n");
    return 1;
}

static int pcmPlayer_init(int channels, int samplerate, int bits_per_sample) {
    SLresult result;

    // 保存音频参数
    g_channels = channels;
    g_samplerate = samplerate;
    g_bits_per_sample = bits_per_sample;

    // 创建引擎
    result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);
    if (SL_RESULT_SUCCESS != result) {
        elog("slCreateEngine failed: %d\n", result);
        return -1;
    }

    // 实现引擎
    result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
    if (SL_RESULT_SUCCESS != result) {
        elog("Engine realize failed: %d\n", result);
        return -1;
    }

    // 获取引擎接口
    result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);
    if (SL_RESULT_SUCCESS != result) {
        elog("Get engine interface failed: %d\n", result);
        return -1;
    }

    // 创建输出混音器
    const SLInterfaceID ids[1] = {SL_IID_ENVIRONMENTALREVERB};
    const SLboolean req[1] = {SL_BOOLEAN_FALSE};
    result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 1, ids, req);
    if (SL_RESULT_SUCCESS != result) {
        elog("CreateOutputMix failed: %d\n", result);
        return -1;
    }

    // 实现输出混音器
    result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE);
    if (SL_RESULT_SUCCESS != result) {
        elog("OutputMix realize failed: %d\n", result);
        return -1;
    }

    // 配置音频源
    SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {
        SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, BUFFER_COUNT
    };
    
    SLDataFormat_PCM format_pcm = {
        SL_DATAFORMAT_PCM,
        channels,
        samplerate * 1000, // mSamplesPerSec in milliHertz
        SL_PCMSAMPLEFORMAT_FIXED_16,
        SL_PCMSAMPLEFORMAT_FIXED_16,
        (channels == 1) ? SL_SPEAKER_FRONT_CENTER : 
                         (SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT),
        SL_BYTEORDER_LITTLEENDIAN
    };

    SLDataSource audioSrc = {&loc_bufq, &format_pcm};

    // 配置音频接收器
    SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, outputMixObject};
    SLDataSink audioSnk = {&loc_outmix, NULL};

    // 创建音频播放器
    const SLInterfaceID player_ids[3] = {
        SL_IID_BUFFERQUEUE, 
        SL_IID_VOLUME,
        SL_IID_PLAYBACKRATE
    };
    const SLboolean player_req[3] = {
        SL_BOOLEAN_TRUE, 
        SL_BOOLEAN_TRUE,
        SL_BOOLEAN_FALSE
    };

    result = (*engineEngine)->CreateAudioPlayer(engineEngine, &bqPlayerObject, 
                                                &audioSrc, &audioSnk, 3, player_ids, player_req);
    if (SL_RESULT_SUCCESS != result) {
        elog("CreateAudioPlayer failed: %d\n", result);
        return -1;
    }

    // 实现音频播放器
    result = (*bqPlayerObject)->Realize(bqPlayerObject, SL_BOOLEAN_FALSE);
    if (SL_RESULT_SUCCESS != result) {
        elog("AudioPlayer realize failed: %d\n", result);
        return -1;
    }

    // 获取播放接口
    result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_PLAY, &bqPlayerPlay);
    if (SL_RESULT_SUCCESS != result) {
        elog("Get play interface failed: %d\n", result);
        return -1;
    }

    // 获取缓冲队列接口
    result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_BUFFERQUEUE, &bqPlayerBufferQueue);
    if (SL_RESULT_SUCCESS != result) {
        elog("Get buffer queue interface failed: %d\n", result);
        return -1;
    }

    // 注册缓冲队列回调
    result = (*bqPlayerBufferQueue)->RegisterCallback(bqPlayerBufferQueue, bqPlayerCallback, NULL);
    if (SL_RESULT_SUCCESS != result) {
        elog("Register callback failed: %d\n", result);
        return -1;
    }

    // 获取音量接口
    result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_VOLUME, &bqPlayerVolume);
    if (SL_RESULT_SUCCESS != result) {
        dlog("Get volume interface failed: %d (volume control not available)\n", result);
        bqPlayerVolume = NULL;
    }

    // 初始化缓冲区状态
    for (int i = 0; i < BUFFER_COUNT; i++) {
        buffer_ready[i] = false;
    }
    current_buffer = 0;
    current_state = PLAYER_CMD_STOP;

    // 设置初始播放状态为准备状态
    result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_PLAYING);
    if (SL_RESULT_SUCCESS != result) {
        elog("Set initial play state failed: %d\n", result);
        return -1;
    }
    is_playing = true;

    ilog("OpenSL ES player initialized (channels=%d, rate=%d)\n", channels, samplerate);
    return 0;
}

static int pcmPlayer_setVolume(int db) {
    if (!bqPlayerVolume) {
        dlog("Volume interface not available\n");
        return 50; // 返回默认音量值
    }

    SLresult result;
    
    // 获取当前音量
    SLmillibel currentVolume;
    result = (*bqPlayerVolume)->GetVolumeLevel(bqPlayerVolume, &currentVolume);
    if (SL_RESULT_SUCCESS != result) {
        dlog("Get volume level failed: %d\n", result);
        return 50;
    }

    // 计算新音量 (OpenSL ES使用毫贝尔，范围通常是-9600到0)
    SLmillibel newVolume = currentVolume + (db * 100); // 1dB = 100毫贝尔
    
    // 限制音量范围
    if (newVolume > 0) newVolume = 0;
    if (newVolume < -9600) newVolume = -9600;

    // 设置新音量
    result = (*bqPlayerVolume)->SetVolumeLevel(bqPlayerVolume, newVolume);
    if (SL_RESULT_SUCCESS != result) {
        dlog("Set volume level failed: %d\n", result);
        return (currentVolume + 9600) * 100 / 9600; // 转换为百分比
    }

    dlog("Volume set to %d millibels\n", newVolume);
    
    // 返回归一化的音量值(0-100)
    return (newVolume + 9600) * 100 / 9600;
}

static int pcmPlayer_write(void *pcm_data, int size) {
    if (!bqPlayerBufferQueue || !is_playing) {
        elog("Player not initialized or not playing\n");
        return -1;
    }

    if (size > BUFFER_SIZE) {
        elog("Data size %d exceeds buffer size %d\n", size, BUFFER_SIZE);
        return -1;
    }

    pthread_mutex_lock(&buffer_mutex);
    
    // 等待缓冲区可用
    int buffer_to_use = -1;
    for (int i = 0; i < BUFFER_COUNT; i++) {
        if (!buffer_ready[i]) {
            buffer_to_use = i;
            break;
        }
    }
    
    // 如果没有可用缓冲区，等待
    while (buffer_to_use == -1) {
        pthread_cond_wait(&buffer_cond, &buffer_mutex);
        for (int i = 0; i < BUFFER_COUNT; i++) {
            if (!buffer_ready[i]) {
                buffer_to_use = i;
                break;
            }
        }
    }

    // 复制数据到缓冲区
    memcpy(audio_buffers[buffer_to_use], pcm_data, size);
    buffer_ready[buffer_to_use] = true;

    pthread_mutex_unlock(&buffer_mutex);

    // 将缓冲区加入播放队列
    SLresult result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, 
                                                     audio_buffers[buffer_to_use], size);
    if (SL_RESULT_SUCCESS != result) {
        elog("Enqueue buffer failed: %d\n", result);
        pthread_mutex_lock(&buffer_mutex);
        buffer_ready[buffer_to_use] = false;
        pthread_mutex_unlock(&buffer_mutex);
        return -1;
    }

    return 0;
}

static int pcmPlayer_getParams(int *channels, int *samplerate, int *bits_per_sample) {
    if (!channels || !samplerate || !bits_per_sample) {
        elog("Invalid parameter pointers\n");
        return -1;
    }
    
    *channels = g_channels;
    *samplerate = g_samplerate;
    *bits_per_sample = g_bits_per_sample;
    return 0;
}

static int pcmPlayer_ctrl(player_ctrl_cmd_t cmd, void *arg) {
    SLresult result;
    
    if (cmd == current_state) {
        return 0; // 已经处于请求的状态
    }

    if (!bqPlayerPlay) {
        elog("Player not initialized\n");
        return -1;
    }

    switch (cmd) {
        case PLAYER_CMD_RESUME:
            dlog("OpenSL ES player: Resume\n");
            result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_PLAYING);
            if (SL_RESULT_SUCCESS != result) {
                elog("Set play state to playing failed: %d\n", result);
                return -1;
            }
            is_playing = true;
            current_state = PLAYER_CMD_RESUME;
            break;
            
        case PLAYER_CMD_PAUSE:
            dlog("OpenSL ES player: Pause\n");
            result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_PAUSED);
            if (SL_RESULT_SUCCESS != result) {
                elog("Set play state to paused failed: %d\n", result);
                return -1;
            }
            is_playing = false;
            current_state = PLAYER_CMD_PAUSE;
            break;
            
        case PLAYER_CMD_STOP:
            dlog("OpenSL ES player: Stop\n");
            result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_STOPPED);
            if (SL_RESULT_SUCCESS != result) {
                elog("Set play state to stopped failed: %d\n", result);
                return -1;
            }
            // 清空缓冲队列
            if (bqPlayerBufferQueue) {
                (*bqPlayerBufferQueue)->Clear(bqPlayerBufferQueue);
            }
            is_playing = false;
            current_state = PLAYER_CMD_STOP;
            break;
            
        default:
            elog("Unknown player command %d\n", cmd);
            return -1;
    }
    
    return 0;
}

static int pcmPlayer_deinit() {
    // 停止播放
    if (bqPlayerPlay) {
        (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_STOPPED);
    }

    // 清空缓冲队列
    if (bqPlayerBufferQueue) {
        (*bqPlayerBufferQueue)->Clear(bqPlayerBufferQueue);
    }

    // 销毁音频播放器对象
    if (bqPlayerObject != NULL) {
        (*bqPlayerObject)->Destroy(bqPlayerObject);
        bqPlayerObject = NULL;
        bqPlayerPlay = NULL;
        bqPlayerBufferQueue = NULL;
        bqPlayerVolume = NULL;
    }

    // 销毁输出混音器对象
    if (outputMixObject != NULL) {
        (*outputMixObject)->Destroy(outputMixObject);
        outputMixObject = NULL;
        outputMixEnvironmentalReverb = NULL;
    }

    // 销毁引擎对象
    if (engineObject != NULL) {
        (*engineObject)->Destroy(engineObject);
        engineObject = NULL;
        engineEngine = NULL;
    }

    // 重置状态
    is_playing = false;
    current_state = PLAYER_CMD_STOP;
    
    // 清理缓冲区状态
    pthread_mutex_lock(&buffer_mutex);
    for (int i = 0; i < BUFFER_COUNT; i++) {
        buffer_ready[i] = false;
    }
    current_buffer = 0;
    pthread_mutex_unlock(&buffer_mutex);

    dlog("OpenSL ES player deinitialized\n");
    return 0;
}

// PCM播放器接口结构体
static pcm_player_t pcm_player = {
    .platform = LINUX, // Android基于Linux内核
    .name = "OpenSL ES",
    .check = check_opensles_support,
    .init = pcmPlayer_init,
    .getParams = pcmPlayer_getParams,
    .setVolume = pcmPlayer_setVolume,
    .write = pcmPlayer_write,
    .ctrl = pcmPlayer_ctrl,
    .deinit = pcmPlayer_deinit,
};

/**
 * 自动注册PCM播放器
 */
__attribute__((constructor))
static void auto_register_pcm_player(void) {
    pcmPlayer_register(&pcm_player);
}
